home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / STRING.H < prev    next >
C/C++ Source or Header  |  1992-09-24  |  20KB  |  505 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. //
  4. // Permission is granted to any individual or institution to use, copy, modify,
  5. // and distribute this software, provided that this complete copyright and
  6. // permission notice is maintained, intact, in all copies and supporting
  7. // documentation.
  8. //
  9. // Texas Instruments Incorporated provides this software "as is" without
  10. // express or implied warranty.
  11. //
  12. // Created: MBN 06/27/89 -- Initial design and implementation
  13. // Updated: DKM 07/07/89 -- To work around Xenix 31 char limit:
  14. //                          Shortened is_less_than        to is_lt
  15. //                                    is_greater_than     to is_gt
  16. //                                    is_less_or_equal    to is_le
  17. //                                    is_greater_or_equal to is_ge
  18. //                          Removed is_equal_or_less and is_greater_or_less
  19. // Updated: MBN 08/03/89 -- Changed operator= argument to const
  20. // Updated: LGO 08/09/89 -- Inherit from Generic
  21. // Updated: MBN 09/06/89 -- Added conditional exception handling
  22. // Updated: LGO 10/28/89 -- Removed is_lt, is_gt, is_le, is_ge, is_equal
  23. //                          and is_not_equal (use char* functions instead)
  24. // Updated: LGO 11/07/89 -- Removed strcmp, strncmp
  25. // Updated: MBN 12/15/89 -- Sprinkled "const" all over the place!
  26. // Updated: LGO 01/05/90 -- Removed strchr, strrchr
  27. // Updated: MBN 01/19/90 -- Made operator=(const char*) take a const char*
  28. // Updated: MJF 06/15/90 -- Added inline strncpy(...,int) to remove ambiguity
  29. // Updated: DLS 03/22/91 -- New lite version
  30. // Updated: JAM 08/11/92 -- removed DOS specifics, stdized #includes
  31. // Updated: JAM 09/23/92 -- use CoolEnvelope template instead of macro
  32. //
  33. // The String class provides dynamic, efficient  strings for a C++ application
  34. // programmer.  The string private data consists of a  slot that maintains the
  35. // length  of   the string  (ie.   number of characters),   a  size  slot that
  36. // maintains the  actual number of  bytes allocated to  a string  object char*
  37. // pointer, and a pointer to the first character of the string. In addition, a
  38. // floating point slot can contain a non-negative percentage between 0 and 1.0
  39. // that  indicates   the ratio by which  a   string object  should  grow  when
  40. // necessary.  Finally,  a static for  the  entire  string class  contains the
  41. // allocation size to be used  when a string  object needs to grow dynamically
  42. // if the growth ratio for the particular instance has not been set.  This has
  43. // a default value that may be over-ridden by the user when the constructor is
  44. // invoked.
  45. //
  46. //              String               Virtual Function Table
  47. //           +-----------+                +----------+
  48. //           |  V_Table--+------------->  :Alloc_Size:
  49. //           +-----------+                :  ....    :
  50. //           | Length=16 |                :          :
  51. //           +-----------+                +----------+
  52. //           | size=100  |                
  53. //           +-----------+   
  54. //           | ratio=0.0 |
  55. //           +-----------+       +--------------------- ... --+
  56. //           |   str   --+------>|This is a string            |
  57. //           +-----------+       +--------------------- ... --+
  58. //
  59. //                               \_____________  _____________/
  60. //                                             \/
  61. //                                     100 bytes allocated
  62. //
  63. // There are  several constructors  for  this class.  The   empty  constructor
  64. // initializes a String object and allocates the default size block of memory.
  65. // The second, third,  and fourth constructors  take char, char*,   and String
  66. // arguments, respectively, and initialize the  String object accordingly. The
  67. // fifth and sixth constructors take either a char* or String argument, and an
  68. // integer argument that specifies the initial
  69. //
  70. // The standard ANSI "str____" function names are all overloaded  for use with
  71. // both  char* and   String  objects.   Operators   for  String concatenation,
  72. // assignment, and comparison are also provided.   In  addition, functions for
  73. // case conversion and string token trimming are provided.  Finally, note that
  74. // the operator functions use corresponding functions with the "case" flag set
  75. // to SENSITIVE.  A user can perform case-INSENSITIVE operations by explicitly
  76. // calling the appropriate function.
  77. //
  78.  
  79. #ifndef STRINGH                    // If no String class defined
  80. #define STRINGH                    // Indicate its done now
  81.  
  82. #ifndef CHARH                    // If extended char* not here
  83. #include <cool/char.h>
  84. #endif
  85.  
  86. #include <stdlib.h>        // Include standard c library support
  87.  
  88. #define MEM_BLK_SZ 100
  89.  
  90. //## BC++ 3.1 bug
  91. #undef CoolEnvelope_H
  92. #define CoolEnvelope CoolEnvelope_String
  93.  
  94. template<class CoolLetter> class CoolEnvelope;
  95. class CoolString;
  96. typedef CoolEnvelope<CoolString> CoolStringE;                // forward dec. of envelope
  97.  
  98. class CoolString {  
  99. public:
  100.   CoolString ();                // CoolString x;
  101.   CoolString (char);                // CoolString x = 'A';
  102.   CoolString (const char*);            // CoolString x = "ABCDEFG";
  103.   CoolString (const CoolString&);        // CoolString x = y;
  104.   CoolString (const CoolString&, long);        // CoolString x = y; memory size
  105.   CoolString (const char*, long);        // CoolString x = "ABCDEFG"; size
  106.  
  107.   ~CoolString();                // Destructor for CoolString class
  108.  
  109.   Boolean insert (const char*, long);        // Insert chars at index
  110.   Boolean remove (long, long);            // Remove chars between indexes
  111.   Boolean replace (const char*, long, long);    // Replace chars between index
  112.   void yank (CoolString&, long, long);        // Delete/set to chars at index
  113.   void sub_string (CoolString&, long, long);    // Set to chars between indexes
  114.  
  115.   friend CoolString& strncpy (CoolString&, const char*, long); // Copy "n" chars
  116.   /*inline##*/ friend CoolString& strncpy (CoolString&, const char*, int);
  117.  
  118.   friend ostream& operator<< (ostream&, const CoolString&);
  119.   friend ostream& operator<< (ostream&, const CoolString*);
  120.   
  121.   inline CoolString& operator= (char);        // x = 'A';
  122.   inline CoolString& operator= (const char*);    // x = "ABCDEFG";
  123.   inline CoolString& operator= (const CoolString&);    // x = y;
  124.   inline CoolString& operator= (CoolStringE&);    // from envelope back to string
  125.  
  126.   inline CoolStringE operator+ (char) const;    // Concatenation operators
  127.   inline CoolStringE operator+ (const char*) const;    
  128.  
  129. // Avoid deep copy and concatenate strings in place with envelope
  130. //   inline friend CoolString operator+ (const CoolString&, const CoolString&);
  131.   
  132.   inline CoolString& operator+= (char);        // Concatentation w/ assignment
  133.   inline CoolString& operator+= (const char*);
  134.   inline CoolString& operator+= (const CoolString&);
  135.   
  136.   inline operator const char*() const;        // String to const char*
  137.   void reverse ();                // Reverse character order
  138.   void clear ();                // Reset NULL terminator
  139.   void resize (long);                // Allocate at least min size
  140.   inline char& operator[] (long i);        // Specific char from CoolString
  141.  
  142.   inline long capacity() const;            // Returns maximum size string 
  143.   inline void set_alloc_size (int);        // Set memory block alloc size
  144.   inline void set_growth_ratio (float);        // Set growth percentage
  145.   
  146.   inline Boolean operator== (const CoolString&) const; // Equality operator
  147.   inline Boolean operator== (const char*) const;
  148.   
  149.   inline Boolean operator!= (const CoolString&) const; // Inequality operator
  150.   inline Boolean operator!= (const char*) const;
  151.   
  152.   inline Boolean operator< (const CoolString&) const; // Lexical less than
  153.   inline Boolean operator< (const char*) const;
  154.   
  155.   inline Boolean operator> (const CoolString&) const; // Lexical greater than
  156.   inline Boolean operator> (const char*) const;
  157.   
  158.   inline Boolean operator<= (const CoolString&) const; // Lexical less than/equal
  159.   inline Boolean operator<= (const char*) const;
  160.   
  161.   inline Boolean operator>= (const CoolString&) const; // Lexical greater than/eq
  162.   inline Boolean operator>= (const char*) const;
  163.   
  164.   /*inline##*/ friend long strlen (const CoolString&);    // Return length of string
  165.   friend CoolString& strcat(CoolString&, const CoolString&); // Appends a copy of second
  166.   friend CoolString& strcat (CoolString&, const char*);
  167.   friend CoolString& strcat (CoolString&, char);
  168.   
  169.   friend CoolString& strncat (CoolString&, const CoolString&, int); // Append "n" chars
  170.   friend CoolString& strncat (CoolString&, const char*, int);
  171.   
  172.   friend CoolString& strcpy (CoolString&, char);    // CoolString copy functions
  173.   friend CoolString& strcpy (CoolString&, const char*);
  174.   friend CoolString& strcpy (CoolString&, const CoolString&); 
  175.   
  176.   friend long strtol(const CoolString&, char** ptr=NULL, int radix=10); // to long
  177.   friend long atol (const CoolString&);        // Convert string to long
  178.   friend int atoi (const CoolString&);        // Convert string to int
  179.   
  180.   friend double strtod (const CoolString&, char** ptr=NULL); // string to double
  181.   /*inline##*/ friend double atof (const CoolString&);    // Convert string to double
  182.   
  183.   friend CoolString& trim (CoolString&, const char*);        // Trim characters 
  184.   friend CoolString& left_trim (CoolString&, const char*);  // Trim prefix chars
  185.   friend CoolString& right_trim (CoolString&, const char*); // Trim suffix chars
  186.   
  187.   friend CoolString& upcase (CoolString&);        // Convert CoolString to upper 
  188.   friend CoolString& downcase (CoolString&);        // Convert string to lower
  189.   friend CoolString& capitalize (CoolString&);        // Capitalize each word
  190.  
  191. private:
  192.   long length;                    // Number of characters 
  193.   long size;                    // Allocated memory size
  194.   char* str;                    // Pointer to string
  195.   float growth_ratio;                // If non-zero, grow by %
  196.   static int alloc_size_s;            // Memory growth size
  197.  
  198.   void bracket_error (long);            // Raise exception
  199.   void growth_error (int);            // Raise exception
  200.   void ratio_error (float);            // Raise exception
  201.   friend void update_memory (CoolString&);        // Adjust memory size
  202. };
  203.  
  204.  
  205.  
  206. // Avoid deep copy, and concatenate strings in place with envelope
  207. #include <cool/Envelope.h>            // Include envelope template
  208.  
  209. // Avoid deep copy and concatenate strings in place with envelope
  210. inline CoolEnvelope<CoolString> operator+ (const CoolString&arg1, const CoolString&arg2)
  211.    { return CoolEnvOp(add)(arg1, arg2); }
  212.  
  213.  
  214. // operator[] -- Return a single character element from CoolString
  215. // Input:        this* CoolString pointer, index "i"
  216. // Output:       The "ith-1" character from CoolString
  217.  
  218. inline char& CoolString::operator[] (long i) {
  219. #if ERROR_CHECKING
  220.   if (i > this->length)                // If index out of range
  221.     this->bracket_error (i);            // Raise exception
  222. #endif
  223.   return (this->str[i]);
  224. }
  225.  
  226.  
  227. // capacity -- Determine the maximum size string possible with growing
  228. // Input:      None
  229. // Output:     Maximum number of characters before growth is required
  230.  
  231. inline long CoolString::capacity() const {
  232.   return (this->size-1);            // Allocated size -1 for NULL
  233. }
  234.  
  235.  
  236. // set_alloc_size -- Set the default allocation size growth rate
  237. // Input:            Growth size in number of elements
  238. // Output:           None
  239.  
  240. inline void CoolString::set_alloc_size (int n) {
  241. #if ERROR_CHECKING
  242.   if (n < 0)                    // If negative growth size
  243.     this->growth_error (n);            // Raise exception
  244. #endif
  245.   this->alloc_size_s = n;            // Set growth size
  246. }
  247.  
  248.  
  249. // set_growth_ratio -- Set the growth percentage for this instance of String
  250. // Input:              Percentage growth rat
  251. // Output:             None
  252.  
  253. inline void CoolString::set_growth_ratio (float ratio) {
  254. #if ERROR_CHECKING
  255.   if (ratio <= 0.0)                // If negative growth factor
  256.     this->ratio_error (ratio);            // Raise exception
  257. #endif
  258.   this->growth_ratio = ratio;            // Set growth size
  259. }
  260.  
  261.  
  262. // operator const char* -- Provide an accessor to the String character pointer
  263. // Input:            this* CoolString pointer
  264. // Output:           this->str character pointer
  265.  
  266. inline CoolString::operator const char*() const {return this->str;}
  267.  
  268. // operator= -- CoolString assignment to a single character: x = 'A';
  269. // Input:       Single character
  270. // Output:      CoolString object containing character string
  271.  
  272. inline CoolString& CoolString::operator= (char c) {
  273.   return (strcpy (*this, c));            
  274. }
  275.  
  276.  
  277. // operator= -- CoolString assignment to a character string: x = "ABCDEFG";
  278. // Input:       Character string
  279. // Output:      CoolString object containing character string
  280.  
  281. inline CoolString& CoolString::operator= (const char* c) {
  282.   return (strcpy (*this, c));            
  283. }
  284.  
  285.  
  286. // operator= -- CoolString assignment to another CoolString: x = y;
  287. // Input:       Reference to CoolString object
  288. // Output:      CoolString object sharing memory with other CoolString
  289.  
  290. inline CoolString& CoolString::operator= (const CoolString& s) {
  291.   return (strcpy (*this, s));            
  292. }
  293.  
  294. // operator=  -- Assignment from an envelope back to real string
  295. // Input:     envelope reference
  296. // Output:    string reference with contents in envelope being swapped over
  297.  
  298. inline CoolString& CoolString::operator= (CoolStringE& env){
  299.   env.shallow_swap((CoolStringE*)this, &env);    // same physical layout
  300.   return *this;
  301. }
  302.  
  303.  
  304. // operator+= -- CoolString concatenation of a character: x += 'A';
  305. // Input:        Character
  306. // Output:       CoolString object concatenated with character
  307.  
  308. inline CoolString& CoolString::operator+= (char c) {
  309.   return (strcat (*this, c));        
  310. }
  311.  
  312. // operator+ -- CoolString concatenation of a character: x = x + 'A';
  313. // Input:       Character
  314. // Output:      new CoolString object concatenated with character
  315.  
  316. inline CoolStringE CoolString::operator+ (char c) const {
  317.   CoolString temp(*this);            // Temporary string
  318.   temp += c;                    // Concatenate temp with c
  319.   CoolStringE& result = (CoolStringE&) temp;    // same physical object
  320.   return result;                // copy of envelope
  321. }
  322.  
  323. // operator+= -- CoolString concatenation of a character string: x += "ABCDEFG";
  324. // Input:        Character CoolString
  325. // Output:       CoolString object concatenated with character CoolString
  326.  
  327. inline CoolString& CoolString::operator+= (const char* c) {
  328.   return (strcat (*this, c));        
  329. }
  330.  
  331.  
  332. // operator+ -- CoolString concatenation of a character string: x = x + "ABCDEFG";
  333. // Input:       Character string
  334. // Output:      CoolString object concatenated with character string
  335.  
  336. inline CoolStringE CoolString::operator+ (const char* c) const {
  337.   CoolString temp(*this);            // Temporary string
  338.   temp += c;                    // Concatenate temp with c
  339.   CoolStringE& result = (CoolStringE&) temp;    // same physical object
  340.   return result;                // copy of envelope
  341. }
  342.  
  343. // operator+= -- CoolString concatenation of another string: x += y;
  344. // Input:        CoolString reference
  345. // Output:       CoolString object concatenated with CoolString contents
  346.  
  347. inline CoolString& CoolString::operator+= (const CoolString& s) {
  348.   return (strcat (*this, s));        
  349. }
  350.  
  351.  
  352. // operator+ -- CoolString concatenation of another string: x = x + y;
  353. //              Implemented as a friend function in CoolEnvelope
  354. // Input:       CoolString reference
  355. // Output:      CoolString object concatenated with CoolString contents
  356.  
  357. // CoolString CoolString::operator+ (const CoolString& s) const {
  358. //   CoolString temp(*this);            // Temporary string
  359. //   strcat(temp, s);                // Concatenate temp with s
  360. //   return temp;                // Return by value
  361. // }
  362.  
  363.  
  364. // operator== -- Test for equality of two CoolString objects
  365. // Input:        this* CoolString pointer, CoolString reference
  366. // Output:       Boolean TRUE/FALSE
  367.  
  368. inline Boolean CoolString::operator== (const CoolString& s) const {
  369.   return (is_equal (*this, s.str, SENSITIVE));
  370. }
  371.  
  372.  
  373. // operator== -- Test for equality of a CoolString and char*
  374. // Input:        this* CoolString pointer, char* pointer
  375. // Output:       Boolean TRUE/FALSE
  376.  
  377. inline Boolean CoolString::operator== (const char* c) const {
  378.   return (is_equal (*this, c, SENSITIVE));
  379. }
  380.  
  381.  
  382. // operator!= -- Test for inequality of two CoolString objects
  383. // Input:        this* CoolString pointer, CoolString reference
  384. // Output:       Boolean TRUE/FALSE
  385.  
  386. inline Boolean CoolString::operator!= (const CoolString& s) const {
  387.   return (is_not_equal (*this, s.str, SENSITIVE));
  388. }
  389.  
  390.  
  391. // operator!= -- Test for inequality of two CoolString objects
  392. // Input:        this* CoolString pointer, char* pointer
  393. // Output:       Boolean TRUE/FALSE
  394.  
  395. inline Boolean CoolString::operator!= (const char* c) const {
  396.   return (is_not_equal (*this, c, SENSITIVE));
  397. }
  398.  
  399.  
  400. // operator< -- Test for lexical ordering before a CoolString
  401. // Input:       this* CoolString pointer, CoolString reference
  402. // Output:      Boolean TRUE/FALSE
  403.  
  404. inline Boolean CoolString::operator< (const CoolString& s) const {
  405.   return (is_lt (*this, s.str, SENSITIVE));
  406. }
  407.  
  408.  
  409. // operator< -- Test for lexical ordering before a CoolString
  410. // Input:       this* CoolString pointer, char* pointer
  411. // Output:      Boolean TRUE/FALSE
  412.  
  413. inline Boolean CoolString::operator< (const char* c) const {
  414.   return (is_lt (*this, c, SENSITIVE));
  415. }
  416.  
  417.  
  418. // operator> -- Test for lexical ordering after a CoolString
  419. // Input:       this* CoolString pointer, CoolString reference
  420. // Output:      Boolean TRUE/FALSE
  421.  
  422. inline Boolean CoolString::operator> (const CoolString& s) const {
  423.   return (is_gt (*this, s.str, SENSITIVE));
  424. }
  425.  
  426.  
  427. // operator> -- Test for lexical ordering after a CoolString
  428. // Input:       this* CoolString pointer, char* pointer
  429. // Output:      Boolean TRUE/FALSE
  430.  
  431. inline Boolean CoolString::operator> (const char* c) const {
  432.   return (is_gt (*this, c, SENSITIVE));
  433. }
  434.  
  435.  
  436. // operator<= -- Test for lexical ordering before or equal to a CoolString
  437. // Input:        this* CoolString pointer, CoolString reference
  438. // Output:       Boolean TRUE/FALSE
  439.  
  440. inline Boolean CoolString::operator<= (const CoolString& s) const {
  441.   return (is_le (*this, s.str, SENSITIVE));
  442. }
  443.  
  444.  
  445. // operator<= -- Test for lexical ordering before or equal to a CoolString
  446. // Input:        this* CoolString pointer, char* pointer
  447. // Output:       Boolean TRUE/FALSE
  448.  
  449. inline Boolean CoolString::operator<= (const char* c) const {
  450.   return (is_le (*this, c, SENSITIVE));
  451. }
  452.  
  453.  
  454. // operator>= -- Test for lexical ordering after or equal to a CoolString
  455. // Input:        this* CoolString pointer, CoolString reference
  456. // Output:       Boolean TRUE/FALSE
  457.  
  458. inline Boolean CoolString::operator>= (const CoolString& s) const {
  459.   return (is_ge (*this, s.str, SENSITIVE));
  460. }
  461.  
  462.  
  463. // operator>= -- Test for lexical ordering after or equal to a CoolString
  464. // Input:        this* CoolString pointer, char* pointer
  465. // Output:       Boolean TRUE/FALSE
  466.  
  467. inline Boolean CoolString::operator>= (const char* c) const {
  468.   return (is_ge (*this, c, SENSITIVE));
  469. }
  470.  
  471.  
  472. // strlen -- Return the number of characters in the CoolString
  473. // Input:    CoolString reference
  474. // Output:   Length of the string
  475.  
  476. inline long strlen (const CoolString& s) {
  477.   return (s.length);
  478. }
  479.  
  480.  
  481. // atof -- Equivalent to strtod (str, (char**)END_OF_STRING)
  482. // Input:  Reference to CoolString object
  483. // Output: Double representing value contained in CoolString
  484.  
  485. inline double atof (const CoolString& s) {
  486.   return (strtod ((char *)s.str, (char **) END_OF_STRING));
  487. }
  488.  
  489.  
  490. // strncpy -- Returns s, with the first length characters of source copied
  491. //            into it.  The old value of s is lost.
  492. // Input   -- A reference to a CoolString s, a char* source, and an int length.
  493. // Output  -- The modified CoolString s.
  494.  
  495. inline CoolString& strncpy(CoolString& s, const char* source, int n) {
  496.   return strncpy(s, source, (long) n);
  497. }
  498.  
  499. //## BC++ 3.1 bug
  500. #undef CoolEnvelope
  501.  
  502. #endif                        // End #ifdef of STRINGH
  503.  
  504.  
  505.